home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 363_01 / miscel.c < prev    next >
C/C++ Source or Header  |  1991-12-15  |  30KB  |  958 lines

  1. /***********************************************************************
  2.  *
  3.  *      MISCEL - Routines for 68020 Assembler
  4.  *      Routines for instructions:
  5.  *          BKPT, CALLM,
  6.  *
  7.  *  All functions accept the same parameters:
  8.  *
  9.  *      tablePtr - pointer to the instruction table,
  10.  *      size      - not used. Included for compatibility with the opDescriptor
  11.  *                  struct definition.
  12.  *      label    - pointer to the label string, empty string if no label
  13.  *      op       - pointer to the input string,
  14.  *      errorPtr - pointer to the error flag.
  15.  *
  16.  *   and return integer flag.
  17.  *
  18.  *   The functions return an error code in *errorPtr using the standard
  19.  *   mechanism.
  20.  *
  21.  *
  22.  *      Author: Andrew E. Romer. Version 1.0
  23.  *      38 Bolsover Road, Worthing, West Sussex, England BN13 1NT.
  24.  *
  25.  *      Date: May 1991
  26.  *
  27.  ***********************************************************************/
  28.  
  29.  
  30. #include <stdio.h>
  31. #include <ctype.h>
  32. #include <string.h>
  33. #include "asm.h"
  34.  
  35. extern long loc;
  36. extern char pass2;
  37.  
  38. /***********************************************************************
  39.  *
  40.  *  Function bkPoint builds the instruction
  41.  *   BKPT #<data>
  42.  *
  43.  ***********************************************************************/
  44.  
  45. #define     BKPT_MASK       0x4848
  46.  
  47. int bkPoint(instruction *tablePtr, int size, char *label, char *op,
  48.                                                             int *errorPtr)
  49.     {
  50.     opDescriptor source;
  51.  
  52. /* op points to the first character of the operand field */
  53.  
  54. /* Move location counter to a word boundary and fix the listing before
  55.  * assembling the instruction */
  56.  
  57.     if (loc & 1)                         /* if not at word boundary */
  58.         {
  59.         loc++;
  60.         listLoc();
  61.         }
  62.  
  63.     if (*label)
  64.         {
  65.         create(label, loc, errorPtr);
  66.         if (*errorPtr > SEVERE)
  67.             return NORMAL;
  68.         }
  69.  
  70.     if (size)
  71.         NEWERROR(*errorPtr, UNSIZED);
  72.  
  73.     op = opParse(op, &source, errorPtr);
  74.     if (*errorPtr > SEVERE)
  75.         return NORMAL;
  76.     if (source.mode != Immediate)
  77.         {
  78.         NEWERROR(*errorPtr, INV_ADDR_MODE);
  79.         return NULL;
  80.         }
  81.     if (!isspace(*op) && *op != '\0')
  82.                             /* if operand field contains
  83.                              * superfluous characters */
  84.         {
  85.         NEWERROR(*errorPtr, SYNTAX);
  86.         return NORMAL;
  87.         }
  88.     if (pass2)
  89.         {
  90.         output( (long) (BKPT_MASK | (source.data & 0x7)), WORD);
  91.         if (source.data < 0 || source.data > 7)
  92.             NEWERROR(*errorPtr, INV_3_BIT_DATA);
  93.         }
  94.     loc += 2;
  95.     }
  96.  
  97. /***********************************************************************
  98.  *
  99.  *  Function callModule builds the instruction
  100.  *   CALLM #<data>,<ea>
  101.  *
  102.  ***********************************************************************/
  103.  
  104. #define     CALLM_MASK      0x06c0
  105.  
  106. int callModule(instruction *tablePtr, int size, char *label, char *op,
  107.                                                             int *errorPtr)
  108.     {
  109.     opDescriptor source, dest;
  110.  
  111. /* op points to the first character of the operand field */
  112.  
  113. /* Move location counter to a word boundary and fix the listing before
  114.  * assembling the instruction */
  115.  
  116.     if (loc & 1)                         /* if not at word boundary */
  117.         {
  118.         loc++;
  119.         listLoc();
  120.         }
  121.  
  122.     if (*label)
  123.         {
  124.         create(label, loc, errorPtr);
  125.         if (*errorPtr > SEVERE)
  126.             return NORMAL;
  127.         }
  128.  
  129.     if (size)
  130.         NEWERROR(*errorPtr, UNSIZED);
  131.  
  132.     op = opParse(op, &source, errorPtr);                /* parse source */
  133.     if (*errorPtr > SEVERE)
  134.         return NORMAL;
  135.     if (source.mode != Immediate)
  136.         {
  137.         NEWERROR(*errorPtr, INV_ADDR_MODE);
  138.         return NULL;
  139.         }
  140.     if (*op != ',')             /* missing source/destination separator */
  141.         {
  142.         NEWERROR(*errorPtr, SYNTAX);
  143.         return NORMAL;
  144.         }
  145.     op = opParse(op+1, &dest, errorPtr);
  146.     if (*errorPtr > SEVERE)
  147.         return NORMAL;
  148.     if ((dest.mode & Control) == 0)
  149.         {
  150.         NEWERROR(*errorPtr, INV_ADDR_MODE);
  151.         return NULL;
  152.         }
  153.     if (!isspace(*op) && *op != '\0')
  154.                             /* if operand field contains
  155.                              * superfluous characters */
  156.         {
  157.         NEWERROR(*errorPtr, SYNTAX);
  158.         return NORMAL;
  159.         }
  160.     if (pass2)
  161.         output( (long) (CALLM_MASK | effAddr(&dest)), WORD);
  162.     loc += 2;
  163.     if (pass2)
  164.         {
  165.         output( (long) (source.data & 0xff), WORD);
  166.  
  167.         if (source.data < 0 || source.data > 255)
  168.             NEWERROR(*errorPtr, INV_8_BIT_DATA);
  169.         }
  170.     loc += 2;
  171.     extWords(&dest, size, errorPtr);
  172.     return NORMAL;
  173.     }
  174.  
  175. /***********************************************************************
  176.  *
  177.  *  Function comSwap builds the instruction
  178.  *   CAS Dc,Du,<ea>
  179.  *
  180.  ***********************************************************************/
  181.  
  182. #define     isRegNum(c)     ((c >= '0') && (c <= '7'))
  183. #define     CAS_BYTEMASK    0x0ac0
  184. #define     CAS_WORDMASK    0x0cc0
  185. #define     CAS_LONGMASK    0x0ec0
  186.  
  187. int compSwap(instruction *tablePtr, int size, char *label, char *op,
  188.                                                             int *errorPtr)
  189.     {
  190.     opDescriptor source;
  191.     char regc, regu;
  192.  
  193. /* op points to the first character of the operand field */
  194.  
  195. /* Move location counter to a word boundary and fix the listing before
  196.  * assembling the instruction */
  197.  
  198.     if (loc & 1)                         /* if not at word boundary */
  199.         {
  200.         loc++;
  201.         listLoc();
  202.         }
  203.  
  204.     if (*label)
  205.         {
  206.         create(label, loc, errorPtr);
  207.         if (*errorPtr > SEVERE)
  208.             return NORMAL;
  209.         }
  210. /* Parse Dc and Du */
  211.     if (op[0] == 'D' && isRegNum(op[1]) && op[2] == ',' && op[3] == 'D'
  212.                     && isRegNum(op[4]) && op[5] == ',')
  213.         {
  214.         regc = op[1] - '0';
  215.         regu = op[4] - '0';
  216.         }
  217.     else
  218.         {
  219.         NEWERROR(*errorPtr, SYNTAX);
  220.         return NORMAL;
  221.         }
  222.  
  223. /* Parse effective address */
  224.     op = opParse(op+6, &source, errorPtr);
  225.     if (*errorPtr > SEVERE)
  226.         return NORMAL;
  227.     if ((source.mode & MemAlt) == 0)
  228.         {
  229.         NEWERROR(*errorPtr, INV_ADDR_MODE);
  230.         return NULL;
  231.         }
  232.     if (!isspace(*op) && *op != '\0')
  233.                             /* if operand field contains
  234.                              * superfluous characters */
  235.         {
  236.         NEWERROR(*errorPtr, SYNTAX);
  237.         return NORMAL;
  238.         }
  239. /* generate output */
  240.     if (pass2)
  241.         switch (size)
  242.             {
  243.             case BYTE:
  244.                 output( (long) (CAS_BYTEMASK | effAddr(&source)), WORD);
  245.                 break;
  246.             case LONG:
  247.                 output( (long) (CAS_LONGMASK | effAddr(&source)), WORD);
  248.                 break;
  249.             default:        /* size == WORD || size == 0 */
  250.                 output( (long) (CAS_WORDMASK | effAddr(&source)), WORD);
  251.                 break;
  252.             }
  253.     loc += 2;
  254.     if (pass2)
  255.         output( (long) ((regu << 6) | regc), WORD);
  256.     loc += 2;
  257.     extWords(&source, size, errorPtr);
  258.     return NORMAL;
  259.     }
  260.  
  261. /***********************************************************************
  262.  *
  263.  *  Function comSwap2 builds the instruction
  264.  *   CAS2 Dc1:Dc2,Du1:Du2,(Rn1):(Rn2)
  265.  *
  266.  ***********************************************************************/
  267.  
  268. #define     CAS2_WORDMASK   0x0cfc
  269. #define     CAS2_LONGMASK   0x0efc
  270.  
  271. int compSwap2(instruction *tablePtr, int size, char *label, char *op,
  272.                                                             int *errorPtr)
  273.     {
  274.     opDescriptor source, dest;
  275.     char regc1, regc2, regu1, regu2, regn1, regn2;
  276.  
  277. /* op points to the first character of the operand field */
  278.  
  279. /* Move location counter to a word boundary and fix the listing before
  280.  * assembling the instruction */
  281.  
  282.     if (loc & 1)                         /* i